//
// Created by wujehy on 2020/5/29.
//

#ifndef GEEJOAN_KEYVALUEBASE_H
#define GEEJOAN_KEYVALUEBASE_H

#include "KeyValueDataType.h"
#include <iostream>
#include <map>
#include <memory>
/**
 * @brief 实现基本的 Key Value 映射表
 */

namespace GeeJoan
{
    namespace DataBase
    {
        typedef std::function<void()> TaskFunction;
        typedef std::shared_ptr<KeyValueDataType> KeyValueDataTypePort;
        typedef std::function<void(std::string key, KeyValueDataTypePort port)> ForEchoCallbackFunction;

        class KeyValueBase
        {
        protected:
            std::map<std::string, KeyValueDataTypePort> cacheKeyValueMap; ///< 缓冲表
        public:
            /**
             * @brief 设置一个 KV 存在则 移除 再添加到map ,
             * @tparam T 基本类型
             * @param key String 描述
             * @param value
             */
            template<typename T>
            void Set(std::string &key, const T &value)
            {
                auto find = cacheKeyValueMap.find( key );
                // 已存在 删除 旧的 插入新的
                if (find != cacheKeyValueMap.end())
                {
                    cacheKeyValueMap.erase( find );
                }
                cacheKeyValueMap[key] = std::shared_ptr<KeyValueDataType>( new KeyValueDataType( value ));
            }

            template<typename T>
            void Set2(std::string key, T value)
            {
                Set( key, value );
            }

            KeyValueDataTypePort Get(std::string &key);

            KeyValueDataTypePort Get2(std::string key);

            void ForEcho(ForEchoCallbackFunction callbackFunction);

            void setUserKey(std::string key, void *port, UserPortDeleteFunction deleteFunction);

            virtual ~KeyValueBase();
        };


        /**
         * @brief TODO KeyValue 持久化接口
         */
        class KeyValueFileImpl
        {

            const std::string suffixdb = "geedb";
            const std::string suffixcfg = "geecfg";

            /**
             * @brief 设置 缓存的文件名
             * @param mFileName
             */
            virtual void setMFileName(const std::string &mFileName) = 0;

            /**
             * @brief 设置 缓存 加密密钥
             * @param mSecretKey
             */
            virtual void setMSecretKey(const std::string &mSecretKey) = 0;

            /**
             * @brief 执行保存操作
             */
            virtual void save() = 0;

            /**
             * @brief  执行加载操作
             */
            virtual void load() = 0;

            /**
             * @brief 解密方法
             * @param inString 秘文
             * @param outString 原文
             */
            virtual void DeciptherFunction(std::string &inString, std::string &outString) = 0;

            /**
             * @brief 解密方法
             * @param inString 原文
             * @param outString 密问
             */
            virtual void EnciptherFunction(std::string &inString, std::string &outString) = 0;

            /**
             * @brief 编码 数据
             * @param inData 数据
             * @param outString 编码后的 值
             */
            virtual void EnCodeFunction(KeyValueDataTypePort inData, std::string &outString) = 0;

            /**
             * @brief 解码 数据
             * @param inString  编码后的值
             * @param outString 原始数据
             */
            virtual void DeCodeFunction(std::string &inString, KeyValueDataTypePort inData) = 0;
        };

    }
}
#endif //GEEJOAN_KEYVALUEBASE_H

